/*
 * Project: com.mmall.user.provider
 *
 * File Created at 2019-10-16
 *
 * Copyright 2019 CMCC Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * ZYHY Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license.
 */
package com.mmall.user.provider.service;

import com.common.framework.bo.TokenBO;
import com.common.framework.constant.DOStatus;
import com.common.framework.dto.TokenDTO;
import com.common.framework.util.CacheUtils;
import com.common.framework.util.Util;
import com.mmall.common.spring.security.impl.JWTAuthHelperImpl;
import com.mmall.common.spring.service.IDGenerateService;
import com.mmall.common.spring.service.RedisService;
import com.mmall.user.api.bo.UserBO;
import com.mmall.user.api.constant.ConstantError;
import com.mmall.user.api.service.UserService;
import com.mmall.user.provider.dao.UserMapper;
import com.mmall.user.provider.model.UserDO;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import static com.common.framework.exception.BusinessException.businessException;

/**
 * @author jianghucoding
 * @date 2019-10-16 22:00
 * @Desc
 */
@Service(version = "1.0.0")
@Component
public class UserServiceImpl implements UserService {

    // -------- 本地注入服务 ---------
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private JWTAuthHelperImpl jwtAuthHelper;

    @Autowired
    private IDGenerateService idGenerateService;

    @Override
    public UserBO getUser(Long id) {
        UserDO user = userMapper.selectById(id);
        if (user == null) {
            throw businessException(ConstantError.USER_NOT_FOUND);
        }
        UserBO userBO = new UserBO();
        return userBO.setId(user.getId())
            .setAvatar(user.getAvatar())
            .setNickname(user.getNickname());
    }

    @Override
    public TokenBO createUser(Long mobile, String authCode) {
        UserDO userDO = userMapper.selectByMobile(mobile);
        if (userDO != null) {
            throw businessException(ConstantError.ALREADY_REGISTER);
        }
        String cacheAutheCode = String.valueOf(redisService.vGet(CacheUtils.CacheName.PHONE_AUTH_CODE, String.valueOf(mobile)));
        if (!authCode.equals(cacheAutheCode)) {
            throw businessException(ConstantError.PHONE_AUTH_CODE_ERROR);
        }
        long id = idGenerateService.generateID();
        String nickname = Util.getDefaultNickName(mobile);
        userDO = new UserDO();
        userDO.setMobile(mobile).setNickname(nickname).setStatus(DOStatus.ACTIVE).setId(id);
        userMapper.insert(userDO);
        TokenDTO tokenDTO = TokenDTO.builder().userId(id).build();
        return jwtAuthHelper.generateToken(tokenDTO);
    }

    @Override
    public String sendAuthCode(Long phone) {
        // 省略了真实发送短信的场景
        String authCode = Util.getPhoneAuthCode();
        boolean sendSuccess = redisService.vPutIfAbsent(CacheUtils.CacheName.PHONE_AUTH_CODE, String.valueOf(phone), authCode);
        if (!sendSuccess) {
            throw businessException(ConstantError.ALREADY_SEND_PHONE_AUTH_CODE);
        }
        return authCode;
    }

    @Override
    public TokenBO login(Long mobile, String authCode) {
        UserDO userDO = userMapper.selectByMobile(mobile);
        if (userDO == null) {
            throw businessException(ConstantError.USER_NOT_FOUND);
        }
        Object authCodeObj = redisService.vGet(CacheUtils.CacheName.PHONE_AUTH_CODE, String.valueOf(mobile));
        if (authCodeObj == null) {
            throw businessException(ConstantError.PLEASE_RESEND_PHONE_AUTH_CODE);
        }
        if (!authCode.equals(authCodeObj.toString())) {
            throw businessException(ConstantError.PHONE_AUTH_CODE_ERROR);
        }
        TokenDTO tokenDTO = TokenDTO.builder().userId(userDO.getId()).build();
        return jwtAuthHelper.generateToken(tokenDTO);
    }
}
